﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Bzzb.Model;
using Masuit.Tools.Security;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;

namespace Bzzb.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class UserController : ControllerBase
    {
        private readonly ILogger<UserController> _logger;
        private readonly IFreeSql _fsql;
        public UserController(ILogger<UserController> logger, IFreeSql fsql){
            this._logger = logger;
            this._fsql = fsql;
        }

        [HttpPost]
        public async Task<Dictionary<string, Object>> Login([FromForm] User user)
        {
            User loginUser = await _fsql.Select<User>().Where(u => u.Username == user.Username && u.Password == user.Password).ToOneAsync();
            if (loginUser == null)
            {
                return RenderJson(status: "failed", message: "账号/密码错误", code: -1);
            }

            JObject data = JObject.FromObject(loginUser);
            #region 以前多角色代码
            /**
            // 先查询出来用户所在所有部门，再根据所有部门ID查询所有部门权限
            List<long> dppids = new List<long>();
            List<long> dpids = await _fsql.Select<DepartmentUser>().Where(dpu => dpu.Uid == loginUser.Id).ToListAsync(dpu => dpu.Dpid);
            _logger.LogInformation("用户登录查询到的部门" + _fsql.Select<DepartmentUser>().Where(dptu => dptu.Uid == loginUser.Id).ToSql(dpu => dpu.Dpid));
            if (dpids != null && dpids.Count > 0)
            {
                dppids = await _fsql.Select<DepartmentPermission>().Where(dpp => dpids.Contains(dpp.Dpid)).ToListAsync(dptp => dptp.Pmid);
            }
            // 先查询出来用户所在所有角色，再根据所有角色ID查询所有角色权限
            List<long> rpids = new List<long>();
            List<long> rids = await _fsql.Select<RoleUser>().Where(ru => ru.Uid == loginUser.Id).ToListAsync(ru => ru.Rid);
            List<long> rids = await _fsql.Select<RoleUser>().Where(ru => ru.Uid == loginUser.Id).ToListAsync(ru => ru.Rid);
            string pmidsData = "";
            if (rids != null && rids.Count > 0)
            {
                #region 根据前端新加的字段返回
                //Role role = await _fsql.Select<Role>().Where(r => r.Id == rids[0]).ToOneAsync();
                //pmidsData = role.PmidsData;
                #endregion

                rpids = await _fsql.Select<RolePermission>().Where(rp => rids.Contains(rp.Rid)).ToListAsync(rp => rp.Pmid);
            }
            List<long> pmids = dppids.Union(rpids).ToList<long>();
            data.Add("pmids", pmids == null ? null : JArray.FromObject(pmids));
            */
            List<long> pmids = new();
            #endregion
            List<long> rids = await _fsql.Select<RoleUser>().Where(ru => ru.Uid == loginUser.Id).ToListAsync(ru => ru.Rid);
            if (rids?.Count > 0) {
                foreach (var rid in rids)
                {
                    Role role = await _fsql.Select<Role>().Where(r => r.Id == rid).ToOneAsync();
                    if (!string.IsNullOrEmpty(role.PmidsData)){
                        pmids = pmids.Union(JArray.Parse(role.PmidsData).ToObject<List<long>>()).ToList();
                    }
                    //pmids = pmids.Union(role.PmidsData.Split(",", StringSplitOptions.RemoveEmptyEntries).ToList()).ToList();
                }
                
            }
            data.Add("pmidsData", pmids == null ? null : JArray.FromObject(pmids));
            //string token = DateTime.Now.ToString().MDString("lru");
            //int affrows = await _fsql.Update<User>(loginUser.Id).Set(u => u.Token, token).ExecuteAffrowsAsync();
            //loginUser.Token = token;
            return RenderJson(data: data);
        }

        [NonAction]
        protected Dictionary<string, Object> RenderJson(string status = "success", string message = "成功", int code = 0, Object data = null)
        {
            Dictionary<string, Object> result = new Dictionary<string, object>();
            result.Add("status", status);
            result.Add("message", message);
            result.Add("code", code);
            result.Add("data", data);
            return result;
        }
    }
}
